package JasPerl::JSTL::Fmt::DateFormat;

use 5.010;
use strict;
use warnings;

use parent qw(DateTime::Format::CLDR Exporter);

use JasPerl::JSTL::Fmt::TimeZoneWrapper;
use JasPerl::Util::TimeZone;
use DateTime::Locale;
use DateTime::TimeZone;

our $VERSION = 0.1;

our @EXPORT_OK = qw(FULL LONG MEDIUM SHORT DEFAULT);

our %EXPORT_TAGS = (
    styles => [ qw(FULL LONG MEDIUM SHORT DEFAULT) ]
);

use constant {
    FULL => 'full',
    LONG => 'long',
    MEDIUM => 'medium',
    SHORT => 'short',
    DEFAULT => 'default'
};

my %DATE_FORMATS = (
    full    => sub { $_[0]->date_format_full },
    long    => sub { $_[0]->date_format_long },
    medium  => sub { $_[0]->date_format_medium },
    short   => sub { $_[0]->date_format_short },
    default => sub { $_[0]->date_format_default }
);

my %TIME_FORMATS = (
    full    => sub { $_[0]->time_format_full },
    long    => sub { $_[0]->time_format_long },
    medium  => sub { $_[0]->time_format_medium },
    short   => sub { $_[0]->time_format_short },
    default => sub { $_[0]->time_format_default }
);

my %DATE_TIME_FORMATS = (
    full    => sub { $_[0]->datetime_format_full },
    long    => sub { $_[0]->datetime_format_long },
    medium  => sub { $_[0]->datetime_format_medium },
    short   => sub { $_[0]->datetime_format_short },
    default => sub { $_[0]->datetime_format_default }
);

sub new {
    my ($class, $pattern, $locale) = @_;
    $locale //= JasPerl::Util::Locale->get_default();
    $locale = DateTime::Locale->load($locale->as_string);
    return $class->SUPER::new(pattern => $pattern, locale => $locale);
}

sub get_format {
    my ($class, $style, $locale) = @_;
    $locale //= JasPerl::Util::Locale->get_default();
    $locale = DateTime::Locale->load($locale->as_string);

    if (my $method = $DATE_TIME_FORMATS{$style // DEFAULT}) {
        my $pattern = $locale->$method();
        return $class->SUPER::new(pattern => $pattern, locale => $locale);
    } else {
        die "no style: $style";
    }
}

sub get_date_format {
    my ($class, $style, $locale) = @_;
    $locale //= JasPerl::Util::Locale->get_default();
    $locale = DateTime::Locale->load($locale->as_string);

    if (my $method = $DATE_FORMATS{$style // DEFAULT}) {
        my $pattern = $locale->$method();
        return $class->SUPER::new(pattern => $pattern, locale => $locale);
    } else {
        die "no style: $style";
    }
}

sub get_time_format {
    my ($class, $style, $locale) = @_;
    $locale //= JasPerl::Util::Locale->get_default();
    $locale = DateTime::Locale->load($locale->as_string);

    if (my $method = $TIME_FORMATS{$style // DEFAULT}) {
        my $pattern = $locale->$method();
        return $class->SUPER::new(pattern => $pattern, locale => $locale);
    } else {
        die "no style: $style";
    }
}

sub get_time_zone {
    return JasPerl::Util::TimeZone->from($_[0]->time_zone);
}

sub set_time_zone {
    $_[0]->time_zone(JasPerl::JSTL::Fmt::TimeZoneWrapper->new($_[1]));
}

sub format {
    my ($self, $time) = @_;
    $time = $time->get_time() if ref $time;
    my $dt = DateTime->from_epoch(epoch => $time / 1000);
    $dt->set_time_zone($self->time_zone);
    return $self->format_datetime($dt);

}

sub parse {
    my ($self, $string) = @_;
    my $dt = $self->parse_datetime($string);
    return JasPerl::Util::Date->from($dt);
}

1;
